<?php defined('SYSPATH') or die('No direct access');
/**
 * CLI 模式异常处理
 */
class CLI_Exception extends Exception
{

    /**
     * Creates a new CLI exception.
     *
     * @param   string   error message
     * @param   integer  the exception code
     * @param   string   the exception file
     * @param   integer  the exception line
     * @return  void
     */
    public function __construct($message = NULL, $code = 0, $file = NULL, $line = 0)
    {
        parent::__construct();

        $this->message = (string) $message;
        $this->code = (integer) $code;
        $this->file = (string) $file;
        $this->line = (integer) $line;
    }

    /**
     * Inline exception handler, displays the error message, source of the
     * exception, and the stack trace of the error.
     *
     * @uses    CLI_Exception::text
     * @param   object   exception object
     * @return  boolean
     */
    public static function handler(Exception $e)
    {
        try
        {
            // Get the exception information
            $code = $e->getCode();

            // Get the exception backtrace
            $trace = $e->getTrace();

            if ($e instanceof ErrorException)
            {
                if (isset(Kohana::$php_errors[$code]))
                {
                    // Use the human-readable error name
                    $code = Kohana::$php_errors[$code];
                }

                if (version_compare(PHP_VERSION, '5.3', '<'))
                {
                    // Workaround for a bug in ErrorException::getTrace() that exists in
                    // all PHP 5.2 versions. @see http://bugs.php.net/bug.php?id=45895
                    for ($i = count($trace) - 1; $i > 0; --$i)
                    {
                        if (isset($trace[$i - 1]['args']))
                        {
                            // Re-position the args
                            $trace[$i]['args'] = $trace[$i - 1]['args'];

                            // Remove the args
                            unset($trace[$i - 1]['args']);
                        }
                    }
                }
            }

            // Create a text version of the exception
            $error = CLI_Exception::text($e);

            if (is_object(Kohana::$log))
            {
                // Add this exception to the log
                Kohana::$log->add(Kohana::ERROR, $error);

                // Make sure the logs are written
                Kohana::$log->write();
            }

            // Just display the text of the exception
            CLI::output("\n{$error}\n");

            return TRUE;
        }
        catch (Exception $e)
        {
            // Display the exception text
            CLI::output(CLI_Exception::text($e)."\n");

            // Exit with an error status
            exit(1);
        }
    }

    /**
     * Magic object-to-string method.
     *
     *     echo $exception;
     *
     * @uses    CLI_Exception::text
     * @return  string
     */
    public function __toString()
    {
        return CLI_Exception::text($this);
    }

    /**
     * Get a single line of text representing the exception
     *
     * @param   object  Exception
     * @return  string
     */
    public static function text(Exception $e)
    {
        return sprintf('%s ( ~ %s on line %s )',
           strip_tags($e->getMessage()), Kohana::debug_path($e->getFile()), $e->getLine());
    }

}